home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 2000 August: Tool Chest / Dev.CD Aug 00 TC Disk 2.toast / pc / sample code / quicktime / streaming / qtspacketizerreassembler / imaaudiortp / sources / imaaudioqueue.c < prev    next >
Encoding:
C/C++ Source or Header  |  2000-06-23  |  7.1 KB  |  353 lines

  1. /*
  2.     File:        IMAAudioQueue.c
  3.  
  4.     Contains:    Definition of operations for IMAAudioQueue, a queue datatype
  5.                 for IMA audio sample data.
  6.  
  7.     Copyright:    © 1997-1999 by Apple Computer, Inc., all rights reserved.
  8.  
  9. */
  10.  
  11.  
  12.  
  13. #include "IMAAudioQueue.h"
  14. #include "IMAAudioPayload.h"
  15. #include <Math64.h>
  16.  
  17.  
  18.  
  19. static
  20. RTPMPSampleDataParams **
  21. __CopySampleDataParams(
  22.     const RTPMPSampleDataParams *    inSampleDataParams )
  23. {
  24.     RTPMPSampleDataParams **    theResult;
  25.     
  26.     
  27.     theResult =
  28.         REINTERPRET_CAST( RTPMPSampleDataParams ** )(
  29.             NewHandle( sizeof( *inSampleDataParams ) ) );
  30.     
  31.     **theResult = *inSampleDataParams;
  32.     
  33.     return( theResult );
  34. }
  35.  
  36.  
  37.  
  38. static
  39. RTPMPSampleDataParams *
  40. __LockSampleDataParams(
  41.     RTPMPSampleDataParams **    inSampleDataParams )
  42. {
  43.     Handle    theHandle = REINTERPRET_CAST( Handle )( inSampleDataParams );
  44.     
  45.     
  46.     if( HandleZone( theHandle ) == SystemZone() )
  47.         HLock( theHandle );
  48.     else
  49.         HLockHi( theHandle );
  50.     
  51.     return( *inSampleDataParams );
  52. }
  53.  
  54.  
  55.  
  56. static
  57. void
  58. __DisposeSampleDataParams(
  59.     RTPMPSampleDataParams **    inSampleDataParams )
  60. {
  61.     DisposeHandle( REINTERPRET_CAST( Handle )( inSampleDataParams ) );
  62. }
  63.  
  64.  
  65.  
  66. static
  67. UInt64
  68. __ConsumedDuration(
  69.     IMAAudioQueue *        inQueue,
  70.     UInt32                inChannel )
  71. {
  72.     UInt32    theFrameCount;
  73.     UInt64    theSampleCount;
  74.     UInt64    theResult;
  75.     
  76.     
  77.     theFrameCount =
  78.         ( inQueue->__itsConsumedFrameCount + inQueue->__itsChannelCount - inChannel - 1 ) /
  79.             inQueue->__itsChannelCount;
  80.     
  81.     theSampleCount =
  82.         U64Multiply(
  83.             U64SetU( theFrameCount ), U64SetU( kIMAAudioPayloadFrameSampleCount ) );
  84.     
  85.     theResult =
  86.         S64Div(
  87.             U64Multiply(
  88.                 theSampleCount,
  89.                 U64SetU( STATIC_CAST( UInt32 )( kIMAAudioPayloadRTPTimeScale ) << 16 ) ),
  90.             S64SetU( inQueue->__itsIncomingSampleRate ) );
  91.     
  92.     return( theResult );
  93. }
  94.  
  95.  
  96.  
  97. static
  98. UInt64
  99. __DequeuedDuration(
  100.     IMAAudioQueue *        inQueue,
  101.     UInt32                inChannel )
  102. {
  103.     UInt32    theFrameCount;
  104.     UInt64    theSampleCount;
  105.     UInt64    theResult;
  106.     
  107.     
  108.     theFrameCount =
  109.         ( inQueue->__itsDequeuedFrameCount + inQueue->__itsChannelCount - inChannel - 1 ) /
  110.             inQueue->__itsChannelCount;
  111.     
  112.     theSampleCount =
  113.         U64Multiply(
  114.             U64SetU( inQueue->__itsDequeuedFrameCount / inQueue->__itsChannelCount ),
  115.             U64SetU( kIMAAudioPayloadFrameSampleCount ) );
  116.     
  117.     theResult =
  118.         S64Div(
  119.             U64Multiply(
  120.                 theSampleCount,
  121.                 U64SetU( STATIC_CAST( UInt32 )( kIMAAudioPayloadRTPTimeScale ) << 16 ) ),
  122.             S64SetU( inQueue->__itsOutgoingSampleRate ) );
  123.     
  124.     return( theResult );
  125. }
  126.  
  127.  
  128.  
  129. static
  130. void
  131. __GetNextFrame(
  132.     IMAAudioQueue *            inQueue,
  133.     IMAAudioQueueElement *    outElement )
  134. {
  135.     RTPMPSampleDataParams **    theSampleDataParams;
  136.     
  137.     
  138.     theSampleDataParams =
  139.         STATIC_CAST( RTPMPSampleDataParams ** )( QueueHead( &inQueue->__itsQueue ) );
  140.     
  141.     if( inQueue->__itsCurrentOffset >= ( **theSampleDataParams ).dataLength )
  142.     {
  143.         inQueue->__itsCurrentOffset = 0;
  144.         
  145.         QueueDequeue( &inQueue->__itsQueue );
  146.         __DisposeSampleDataParams( theSampleDataParams );
  147.         
  148.         theSampleDataParams =
  149.             STATIC_CAST( RTPMPSampleDataParams ** )( QueueHead( &inQueue->__itsQueue ) );
  150.     }
  151.     
  152.     if( inQueue->__itsCurrentOffset == 0 )
  153.         __LockSampleDataParams( theSampleDataParams );
  154.     
  155.     outElement->itsChannel = inQueue->__itsConsumedFrameCount % inQueue->__itsChannelCount;
  156.     
  157.     outElement->itsTimestamp =
  158.         S64Add(
  159.             inQueue->__itsStartTime,
  160.             __DequeuedDuration( inQueue, outElement->itsChannel ) );
  161.     
  162.     outElement->itsSampleDataParams = *theSampleDataParams;
  163.     outElement->itsOffset = inQueue->__itsCurrentOffset;
  164.     
  165.     inQueue->__itsCurrentOffset += sizeof( IMAAudioFrame );
  166.     --inQueue->__itsFrameCount;
  167.     inQueue->__itsConsumedFrameCount++;
  168. }
  169.  
  170.  
  171.  
  172. static
  173. void
  174. __Reset(
  175.     IMAAudioQueue *        inQueue )
  176. {
  177.     QueueInitialize( &inQueue->__itsQueue );
  178.     inQueue->__itsStartTime = S64SetU( 0 );
  179.     inQueue->__itsFrameCount = 0;
  180.     inQueue->__itsCurrentOffset = 0;
  181.     inQueue->__itsConsumedFrameCount = 0;
  182.     inQueue->__itsDequeuedFrameCount = 0;
  183. }
  184.  
  185.  
  186.  
  187. extern
  188. void
  189. IMAAudioQueueInitialize(
  190.     IMAAudioQueue *        inQueue )
  191. {
  192.     __Reset( inQueue );
  193.     
  194.     IMAAudioQueueSetFlowControl( inQueue, 0, 0, 1 );
  195. }
  196.  
  197.  
  198.  
  199. extern
  200. UnsignedFixed
  201. IMAAudioQueueSetFlowControl(
  202.     IMAAudioQueue *        inQueue,
  203.     UnsignedFixed        inIncomingSampleRate,
  204.     UnsignedFixed        inOutgoingSampleRate,
  205.     UInt16                inChannelCount )
  206. {
  207.     UnsignedFixed    theResult;
  208.     
  209.     
  210.     if( inIncomingSampleRate >= inOutgoingSampleRate )
  211.         theResult = inOutgoingSampleRate;
  212.     else
  213.         theResult = inIncomingSampleRate;
  214.     
  215.     if( inQueue->__itsFrameCount )
  216.     {
  217.         if(
  218.             inIncomingSampleRate != inQueue->__itsIncomingSampleRate  ||
  219.             theResult != inQueue->__itsOutgoingSampleRate )
  220.         {
  221.             IMAAudioQueueFlush( inQueue );
  222.         }
  223.     }
  224.     
  225.     inQueue->__itsIncomingSampleRate = inIncomingSampleRate;
  226.     inQueue->__itsOutgoingSampleRate = theResult;
  227.     inQueue->__itsChannelCount = inChannelCount;
  228.     
  229.     return( theResult );
  230. }
  231.  
  232.  
  233.  
  234. extern
  235. UInt32
  236. IMAAudioQueueCount(
  237.     const IMAAudioQueue *    inQueue )
  238. {
  239.     UInt32    theResult;
  240.     UInt64    theIncomingFrameCount;
  241.     UInt64    theIncomingSampleRate;
  242.     UInt64    theDequeuedFrameCount;
  243.     UInt64    theOutgoingSampleRate;
  244.     UInt64    thePendingTime;
  245.     
  246.     
  247.     if( inQueue->__itsIncomingSampleRate  &&  inQueue->__itsFrameCount )
  248.     {
  249.         theIncomingFrameCount =
  250.             U64SetU( inQueue->__itsConsumedFrameCount + inQueue->__itsFrameCount );
  251.         
  252.         theIncomingSampleRate = U64SetU( inQueue->__itsIncomingSampleRate );
  253.         theDequeuedFrameCount = U64SetU( inQueue->__itsDequeuedFrameCount );
  254.         theOutgoingSampleRate = U64SetU( inQueue->__itsOutgoingSampleRate );
  255.         
  256.         thePendingTime =
  257.             U64Subtract(
  258.                 U64Multiply( theOutgoingSampleRate, theIncomingFrameCount ),
  259.                 U64Multiply( theIncomingSampleRate, theDequeuedFrameCount ) );
  260.         
  261.         theResult = U32SetU( U64Div( thePendingTime, theIncomingSampleRate ) );
  262.         
  263.         if( U64Mod( thePendingTime, theIncomingSampleRate ) )
  264.             theResult++;
  265.     }
  266.     
  267.     else
  268.     {
  269.         theResult = 0;
  270.     }
  271.     
  272.     return( theResult );
  273. }
  274.  
  275.  
  276.  
  277. extern
  278. RTPMPSampleDataParams *
  279. IMAAudioQueueEnqueue(
  280.     IMAAudioQueue *                    inQueue,
  281.     const RTPMPSampleDataParams *    inSampleDataParams )
  282. {
  283.     RTPMPSampleDataParams *        theResult;
  284.     
  285.     
  286.     theResult =
  287.         ( RTPMPSampleDataParams * ) QueueEnqueue(
  288.             &inQueue->__itsQueue, __CopySampleDataParams( inSampleDataParams ) );
  289.     
  290.     if( theResult )
  291.     {
  292.         if( inQueue->__itsFrameCount == 0  &&  inQueue->__itsConsumedFrameCount == 0 )
  293.             inQueue->__itsStartTime = inSampleDataParams->timeStamp;
  294.         
  295.         inQueue->__itsFrameCount +=
  296.             inSampleDataParams->dataLength / sizeof( IMAAudioFrame );
  297.     }
  298.     
  299.     return( theResult );
  300. }
  301.  
  302.  
  303.  
  304. extern
  305. Boolean
  306. IMAAudioQueueDequeue(
  307.     IMAAudioQueue *            inQueue,
  308.     IMAAudioQueueElement *    outElement )
  309. {
  310.     Boolean        theResult = false;
  311.     UInt32        theInitialFrameCount = inQueue->__itsFrameCount;
  312.     
  313.     
  314.     while( inQueue->__itsFrameCount  && !theResult )
  315.     {
  316.         __GetNextFrame( inQueue, outElement );
  317.         
  318.         theResult =
  319.             U64Compare(
  320.                 __ConsumedDuration( inQueue, outElement->itsChannel ),
  321.                 __DequeuedDuration( inQueue, outElement->itsChannel ) ) > 0;
  322.     }
  323.     
  324.     if( theInitialFrameCount > inQueue->__itsFrameCount  && theResult )
  325.         inQueue->__itsDequeuedFrameCount++;
  326.     else
  327.         theResult = false;
  328.     
  329.     return( theResult );
  330. }
  331.  
  332.  
  333.  
  334. extern
  335. void
  336. IMAAudioQueueFlush(
  337.     IMAAudioQueue *        inQueue )
  338. {
  339.     UInt32                        theCount;
  340.     RTPMPSampleDataParams **    theSampleDataParams;
  341.     
  342.     
  343.     for( theCount = QueueCount( &inQueue->__itsQueue ); theCount; --theCount )
  344.     {
  345.         theSampleDataParams =
  346.             STATIC_CAST( RTPMPSampleDataParams ** )( QueueDequeue( &inQueue->__itsQueue ) );
  347.         
  348.         __DisposeSampleDataParams( theSampleDataParams );
  349.     }
  350.     
  351.     __Reset( inQueue );
  352. }
  353.